import React from "react";
import { connect } from "react-redux";
import menuRoute from "routes/menuRoute";
import { messages, ManuelResizeWindow } from "share/common";
import configureStore from "stores";
import { setMenuCollapse, setMenuWidth, setReportMenu } from "actions/main";
import "styles/main/new-menu.scss";
import { Layout, Menu, Icon, Tooltip, Input, message, Tabs } from "antd";
import {
  RenderCompanyName,
  RenderMenuBottomFunc,
  RenderMessagesCenterSvg,
  RenderToolMenuListSvg,
  matchMenuValue,
  resizeWidth,
  onKeyDown,
  inputChange,
  clearMenuSearch,
  renderSelectedKeys,
  checkHasMenuValue,
  checkTabMatchValue,
} from "./menu-share";
import UserInfo from "../user-info";
import routeService from "routes/route.service";
import SVGIcon from "components/SVGIcon";
import RLService from "../../../data-center/report/report-list.service";
import debounce from "lodash.debounce";
import TryRegister from "containers/components/try-register";
const TabPane = Tabs.TabPane;
const SubMenu = Menu.SubMenu;
const { Sider } = Layout;
const menuCollapseWidth = 56;
class NewMenu extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      horizontalKey: null,
      horizontalMenu: null,
      isSearchingMenu: false,
      resultMenu: [],
      menuValue: "",
      check: true,
      error: false,
      errorContent: {},
      hoverKey: "", //搜索菜单时键盘上下移动时选中的菜单key
      selectedKeys: [],
      openKeys: [],
      collapseOpenKeys: [],
      toolMenuList: [],
    };
    this.resizeWindow = debounce(ManuelResizeWindow, 300);
  }
  componentDidMount() {
    this.renderToolMenu();
    const { menuTree } = this.props;
    const horizontalMenu = menuTree.menuTree.find((item) => item.resourceType === "M");
    if (horizontalMenu) {
      this.setState({
        horizontalMenu,
        horizontalKey: horizontalMenu.key,
      });
    }
  }

  componentWillReceiveProps(nextProps) {
    const { horizontalKey } = this.state;
    const { menuTree } = this.props;
    const { currentPageRoute } = nextProps;
    if (currentPageRoute.key === "unbox-setting" && horizontalKey !== "system-management") {
      const horizontalMenu = menuTree.menuTree.find((item) => item.key === "system-management");
      this.setState({
        horizontalMenu,
        horizontalKey: "system-management",
      });
    } else {
      const parent = currentPageRoute.parent;
      const key = parent && parent[0] && parent[0].key;
      if (key && key !== horizontalKey) {
        const horizontalMenu = menuTree.menuTree.find((item) => item.key === key);
        this.setState({
          horizontalMenu,
          horizontalKey: key,
        });
      }
    }
    if (this.props.params.openKeys !== nextProps.params.openKeys) {
      this.setState({
        openKeys: nextProps.params.openKeys,
      });
    }
  }

  renderToolMenu = () => {
    const { menuTree } = this.props;
    const work = menuTree.menuTree.find((item) => item.key === "workflow-management");
    if (work && work.subMenuTree && work.subMenuTree.length) {
      const tool = work.subMenuTree.find((item) => item.key === "toolbar");
      if (tool) {
        this.setState({
          toolMenuList: tool.subMenuTree.filter((item) => !["messages-center", "personal-settings"].includes(item.key)),
        });
      }
    }
  };

  onTabClick = (tab) => {
    const { horizontalKey } = this.state;
    const { menuTree, currentMenuPermission = {} } = this.props;
    const menu = menuTree.menuTree.find((item) => item.key === tab);
    if (horizontalKey === tab) {
      const current = (currentMenuPermission.currentMenu || {}).key;
      if (current === menu.key || current === (menu.subMenuTree[0] || {}).key) {
        return;
      }
    }
    let url = "";
    if (menu) {
      this.setState({
        horizontalMenu: menu,
        resultMenu: [],
        hoverKey: "",
        isSearchingMenu: false,
        menuValue: "",
        horizontalKey: tab,
        selectedKeys: [],
      });
      //如果切换到了系统管理tab，且有管理员权限。进入快捷设置中心
      if (tab === "system-management" && menuTree.keyUrl.home) {
        url = "/main/unbox-setting";
      } else if (tab === "workflow-management") {
        //点击横向菜单【工作台】或者登录。有管理员权限进入管理员首页，否则个人首页
        if (menuTree.keyUrl.home) {
          url = "/main/home";
        }
        if (menuTree.keyUrl.dashboard) {
          url = "/main/dashboard";
        }
        const tempHome = sessionStorage.getItem("hly.tempHome");
        if (tempHome && tempHome === "home") {
          url = menuTree.keyUrl.home;
        } else if (tempHome && tempHome === "dashboard") {
          url = menuTree.keyUrl.dashboard;
        }
      }
      if (url) {
        this.context.router.push(url);
        return;
      }
      if (menu.subMenuTree && menu.subMenuTree.length) {
        const first = menu.subMenuTree[0];
        if (first.subMenuTree && first.subMenuTree.length) {
          url = first.subMenuTree[0].url;
        } else {
          url = first.url;
        }
      }
      this.context.router.push(url);
    }
  };

  goMenuPage = (item) => {
    //自定义报表菜单只有functionCode没有key。明天让后端加上，保持统一就好了。
    if ((item.key || item.functionCode).includes("/")) {
      // 由于报表的类型可能会变，加菜单时存的key也就变了，所以报表类型更改时需要在这里加一下，使其能匹配到更改后的类型
      const idMap = {
        32: "graphic-report",
        7: "universal-report",
        41: "graphic-report",
      };
      this.repeatMenuKey = item.key || item.functionCode;

      let [key, id] = (item.key || item.functionCode).split("/");
      key = idMap[id] || key;
      let url = menuRoute.getPageUrlByKey(key);
      url = url.replace(":id", id);
      url = url.replace(":reportName", item.resourceName);
      this.context.router.push(url);
      return;
    }
    this.context.router.push(item.url);
  };

  handleMenuClick = (e) => {
    let { openKeys, horizontalMenu } = this.state;
    const currentKey = e.key;
    if (currentKey === "data-analysis" && !openKeys.includes("data-analysis")) {
      this.handleReportMenuCheck();
    }
    if (openKeys[0] === currentKey || openKeys[1] === currentKey) {
      openKeys = [];
    } else {
      openKeys = [currentKey];
    }
    this.setState({ openKeys }, () => {
      if (this.state.openKeys.includes(currentKey)) {
        let allMenu = document.getElementById("all-menu-list");
        let currentMenu = document.getElementById(currentKey),
          currentOffsetTop = currentMenu.offsetParent.offsetTop,
          allClientHeight = allMenu.clientHeight,
          target = horizontalMenu.subMenuTree.find((item) => item.key === currentKey),
          index = horizontalMenu.subMenuTree.findIndex((item) => item.key === currentKey);
        let diff = target.subMenuTree.length * 48;
        let bool = diff + currentMenu.offsetHeight >= allClientHeight;
        if (bool) {
          allMenu.scrollTop = currentOffsetTop;
        } else {
          //滚动到把下面一个菜单露出来
          allMenu.scrollTop = (index + 2) * 48 + diff - allClientHeight;
        }
      }
    });
  };
  handleReportMenuCheck = () => {
    RLService.getReportMenuPolicy().then((res) => {
      const { data } = res;
      if (data) {
        configureStore.store.dispatch(setReportMenu(data));
      }
    });
  };
  onOpenChange = (openKeys) => {
    const { menuCollapse } = this.props;
    // if (menuCollapse) this.setState({ openKeys: openKeys.slice(-1) });
    if (menuCollapse) this.setState({ collapseOpenKeys: openKeys });
  };

  showToolTip = (item) => {
    const code = this.props.language.code.toLowerCase();
    return (code === "en" && item.resourceName.length > 17) || (code === "it_it" && item.resourceName.length > 20);
  };
  onClickMenu = ({ item, key, keyPath }) => {
    const { menuTree, reportMenu } = this.props;
    if (key.includes("/")) {
      const report = (reportMenu || []).find((item) => item.key === key);
      if (report) {
        this.goMenuPage(report);
        return;
      }
    }
    this.goMenuPage(menuTree.allAPIMenuItem[key]);
  };

  renderVerticalMenu = (menu) => {
    const {
      hoverKey,
      menuValue,
      openKeys,
      isSearchingMenu,
      horizontalKey,
      collapseOpenKeys,
      selectedKeys,
    } = this.state;
    const { menuCollapse, reportMenu } = this.props;
    const obj = {
      selectedKeys: renderSelectedKeys(selectedKeys, this.props.params.selectedKeys),
      inlineCollapsed: menuCollapse,
      onOpenChange: this.onOpenChange,
      onClick: this.onClickMenu,
      onSelect: (e) => {
        this.setState({ selectedKeys: [e.key] });
      },
    };
    obj.openKeys = menuCollapse ? collapseOpenKeys : openKeys;

    return (
      <Menu mode="inline" {...obj}>
        {menu.map((item, index) => {
          if (["home", "dashboard", "unbox-setting"].includes(item.key) || item.resourceType === "C") {
            return null;
          }
          const showBorder = !isSearchingMenu && index > 0 && item.moduleType !== menu[index - 1].moduleType;
          if (item.subMenuTree && item.subMenuTree.length) {
            return (
              <SubMenu
                key={item.key}
                title={
                  <div
                    className={this.classNames({
                      "text-ellipsis": true,
                      "menu-submenu-title": true,
                      "show-category-border": showBorder,
                    })}
                    id={item.key}
                  >
                    {!menuCollapse && this.showToolTip(item) ? (
                      <Tooltip title={item.resourceName}>
                        {!menuValue && <SVGIcon type={item.key} className="svg-menu-icon" />}
                        <span className="nav-text">
                          {menuValue ? matchMenuValue(item, menuValue) : item.resourceName}
                        </span>
                      </Tooltip>
                    ) : (
                      <div className="text-ellipsis">
                        {!menuValue && <SVGIcon type={item.key} className="svg-menu-icon" />}
                        <span>{menuValue ? matchMenuValue(item, menuValue) : item.resourceName}</span>
                      </div>
                    )}
                  </div>
                }
                onTitleClick={(e) => this.handleMenuClick(e)}
              >
                {item.subMenuTree.map((sub) => {
                  const showTabName = !checkHasMenuValue(sub, menuValue) && checkTabMatchValue(sub, menuValue);
                  return (
                    <Menu.Item key={sub.key}>
                      <div
                        id={sub.key}
                        className={this.classNames({
                          "text-ellipsis": true,
                          "hove-menu-item": hoverKey === sub.key && !showTabName,
                          "hove-menu-item-has-tab": hoverKey === sub.key && showTabName,
                          "single-f-menu": hoverKey !== sub.key && !showTabName,
                          "show-tab-name": hoverKey !== sub.key && showTabName,
                        })}
                        // onClick={() => this.goMenuPage(sub)}
                      >
                        {!menuCollapse && this.showToolTip(sub) ? (
                          <Tooltip title={sub.resourceName}>
                            <span className="nav-text">
                              {menuValue ? matchMenuValue(sub, menuValue) : sub.resourceName}
                              {showTabName && this.renderTabMatchValue(sub, menuValue)}
                            </span>
                          </Tooltip>
                        ) : menuValue ? (
                          <div>
                            {matchMenuValue(sub, menuValue)}
                            {showTabName && this.renderTabMatchValue(sub, menuValue)}
                          </div>
                        ) : (
                          sub.resourceName
                        )}
                      </div>
                    </Menu.Item>
                  );
                })}
              </SubMenu>
            );
          }
          return this.renderMenuItem({ item, index, showBorder });
        })}
        {!isSearchingMenu && horizontalKey === "data-analysis" && reportMenu.length
          ? reportMenu.map((report) => {
              return this.renderMenuItem({ item: report, showBorder: false, iconType: "bar-chart" });
            })
          : null}
      </Menu>
    );
  };

  renderMenuItem = (params) => {
    const { menuCollapse, approveNum, language } = this.props;
    const { menuValue, hoverKey } = this.state;
    const { item, showBorder, iconType } = params;
    const code = language.code.toLowerCase();
    const showTabName = !checkHasMenuValue(item, menuValue) && checkTabMatchValue(item, menuValue);
    return (
      <Menu.Item key={item.key}>
        <div
          id={item.key}
          className={this.classNames({
            "text-ellipsis": true,
            "hove-menu-item": hoverKey === item.key && !showTabName,
            "hove-menu-item-has-tab": hoverKey === item.key && showTabName,
            "single-f-menu": hoverKey !== item.key && !showTabName,
            "show-tab-name": hoverKey !== item.key && showTabName,
            "show-category-border": showBorder,
            "show-category-border-margin": showBorder && !menuCollapse,
          })}
          // onClick={() => this.goMenuPage(item)}
        >
          {!menuCollapse && this.showToolTip(item) ? (
            <Tooltip title={item.resourceName}>
              <span>
                {!menuValue && <SVGIcon type={iconType ? "customize-report" : item.key} className="svg-menu-icon" />}
                <span className="nav-text">{menuValue ? matchMenuValue(item, menuValue) : item.resourceName}</span>
                {showTabName && this.renderTabMatchValue(item, menuValue)}
              </span>
            </Tooltip>
          ) : (
            <div className={this.classNames({ "approve-menu-item": item.key === "approve", "text-ellipsis": true })}>
              {!menuValue && <SVGIcon type={iconType ? "customize-report" : item.key} className="svg-menu-icon" />}
              <span>{menuValue ? matchMenuValue(item, menuValue) : item.resourceName}</span>
              {showTabName && this.renderTabMatchValue(item, menuValue)}
              {!menuCollapse && item.key === "approve" && approveNum > 0 && (
                <div className={menuValue && hoverKey === item.key ? "approve-num approve-num-search" : "approve-num"}>
                  {approveNum > 99 ? "99+" : approveNum}
                </div>
              )}
            </div>
          )}
        </div>
      </Menu.Item>
    );
  };

  renderTabMatchValue = (item, menuValue) => {
    let match = item.subFunctions.filter((sub) => checkHasMenuValue(sub, menuValue));
    if (match && match.length) {
      let len = match.length;
      return (
        <div className="tab-name-block text-ellipsis">
          {match.map((m, index) => {
            const result = matchMenuValue(m, menuValue);
            return index === len - 1 ? result : <span>{result}--</span>;
          })}
        </div>
      );
    }
  };

  delayFlagOff = () => {
    this.setState({ delayFlag: false });
  };
  onCollapse = (collapsed, shouldFocus) => {
    const { isSearchingMenu } = this.state;
    const { tenant } = this.props;
    if (isSearchingMenu && collapsed) {
      this.setState({
        resultMenu: [],
        hoverKey: "",
        isSearchingMenu: false,
        menuValue: "",
      });
    }
    resizeWidth();
    configureStore.store.dispatch(setMenuCollapse(collapsed));
    this.setState({ collapsed, delayFlag: true }, () => {
      this.delayFlagOff();
      this.resizeWindow();
    });
    configureStore.store.dispatch(
      setMenuWidth(
        collapsed ? (tenant.resourceLayout === "T" ? 56 : 64) : this.props.language.code === "it_IT" ? 250 : 220
      )
    );
    shouldFocus &&
      setTimeout(() => {
        this.menuInputRef.focus();
      }, 300);
  };
  //路由跳转
  menuRouterDeal = (item) => {
    routeService.menuRouterDeal(item, this.context, this.props.authToken);
  };
  feedbackRefHandler = () => {
    this.feedbackRef.feedbackHandler();
  };
  mainRoute = menuRoute.getMainRoute();
  render() {
    const { menuCollapse, menuWidth, approveNum, loginUser, menuTree, user } = this.props;
    const { onlineServiceUrl } = this.props.params;
    const {
      horizontalMenu,
      horizontalKey,
      isSearchingMenu,
      resultMenu,
      menuValue,
      toolMenuList,
      hoverKey,
    } = this.state;
    return (
      <div>
        <div className="new-menu-horizontal-menu" id={"new-menu-horizontal-menu-mask-guide"}>
          <div className="new-menu-horizontal-tabs">
            <Tabs activeKey={horizontalKey} onTabClick={this.onTabClick}>
              {menuTree.menuTree.map((item, index) => {
                return (
                  item.resourceType === "M" && (
                    <TabPane
                      tab={
                        <span id={index === 0 ? "first-tab-for-mask-guide" : ""}>
                          {menuTree.allAPIMenuItem.approve && item.key === "workflow-management" && approveNum ? (
                            <span className="workflow-management">
                              {item.resourceName}
                              <span className="approve-red-dot" />
                            </span>
                          ) : (
                            item.resourceName
                          )}
                        </span>
                      }
                      key={item.key}
                    />
                  )
                );
              })}
            </Tabs>
          </div>
          <div className="horizontal-menu-header">
            <RenderMessagesCenterSvg />
            <RenderToolMenuListSvg toolMenuList={toolMenuList} onlineServiceUrl={onlineServiceUrl} />
            <UserInfo loginUser={loginUser} menuRouterDeal={this.menuRouterDeal} />
          </div>
        </div>
        <Sider
          collapsedWidth={menuCollapseWidth}
          width={menuWidth}
          collapsible
          trigger={null}
          collapsed={menuCollapse}
          className="new-menu-sider"
        >
          <div className="new-menu-vertical-menu">
            <RenderCompanyName />
            <div className="menu-body-container" id={"menu-body-container-mask-guide"}>
              <div className="menu-search" id={"menu-search-mask-guide"}>
                <div
                  className={`menu-search-${menuCollapse ? "fold" : "unfold"}`}
                  onClick={() => {
                    menuCollapse && this.onCollapse(false, true);
                  }}
                >
                  <Input
                    ref={(ref) => (this.menuInputRef = ref)}
                    value={menuValue}
                    onKeyDown={(e) => onKeyDown(e, this)}
                    onChange={(e) => inputChange(e, this)}
                    placeholder={messages("basic-1.key79") /*搜索菜单*/}
                    prefix={<Icon type="search" style={{ color: "#848c95" }} />}
                    suffix={
                      menuValue && !menuCollapse ? (
                        <Icon type="close-circle" className="close-circle" onClick={() => clearMenuSearch(this)} />
                      ) : (
                        <span />
                      )
                    }
                  />
                </div>
              </div>
              {isSearchingMenu ? (
                resultMenu.length ? (
                  <div className=" all-menu-list search-result-menu" id="search-result-menu">
                    {this.renderVerticalMenu(resultMenu)}
                  </div>
                ) : (
                  <div className="no-result-menu">{messages("basic-1.key80") /*无相关菜单项*/}&nbsp;&nbsp;</div>
                )
              ) : (
                <div
                  className={this.classNames({ "all-menu-list": true, "all-menu-list-collapsed": menuCollapse })}
                  id="all-menu-list"
                >
                  {horizontalMenu && this.renderVerticalMenu(horizontalMenu.subMenuTree || [])}
                </div>
              )}
              {user.tenantType === "FREE_TRIAL" && <TryRegister />}
              <RenderMenuBottomFunc onlineServiceUrl={onlineServiceUrl} that={this} />
            </div>
          </div>
        </Sider>
      </div>
    );
  }
}

NewMenu.contextTypes = {
  router: React.PropTypes.object,
};

function mapStateToProps(state) {
  return {
    menuTree: state.login.menuTree,
    company: state.login.company,
    tenant: state.login.tenant,
    menuCollapse: state.main.menuCollapse,
    currentMenuPermission: state.main.currentMenuPermission,
    menuWidth: state.main.menuWidth,
    language: state.main.language,
    user: state.login.user,
    currentPageRoute: state.main.currentPageRoute,
    approveNum: state.login.approveNum,
    reportMenu: state.main.reportMenu,
    loginUser: state.login.loginUser,
  };
}

export default connect(mapStateToProps)(NewMenu);
